package org.hcyspartnoc.demo.utils.redis;


import jakarta.annotation.Resource;
import org.hcyspartnoc.demo.common.core.configuration.ContrapsychConfiguration;
import org.hcyspartnoc.demo.common.core.configuration.UserConfiguration;
import org.hcyspartnoc.demo.common.core.configuration.UtilsConfiguration;
import org.hcyspartnoc.demo.common.enums.system.SysPermissionStatusEnum;
import org.hcyspartnoc.demo.common.enums.system.SysRoleStatusEnum;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Component
public class RedisComponent {
    @Resource
    private RedisUtils<Object> redisUtils;
    @Resource
    private UserConfiguration userConfiguration;
    @Resource
    private UtilsConfiguration utilsConfiguration;
    @Resource
    private ContrapsychConfiguration contrapsychConfiguration;

    private static final String GRAPH_TOKEN_UID_PREFIX = "graph:user:token:id:";
    private static final String GRAPH_PERMISSION_PREFIX = "graph:permission";
    private static final String GRAPH_RP_RELATION_PREFIX = "graph:relation:R&P:";
    private static final String GRAPH_ROLE_PREFIX = "graph:role";
    private static final String GRAPH_VISIT_LIMIT_PREFIX = "graph:visit:limit:";
    private static final String GRAPH_RU_ReLATION_PREFIX = "graph:relation:R&U:";
    private static final String GRAPH_CAPTCHA_IMAGE_PREFIX = "graph:captcha:image:";
    private static final String GRAPH_CHAT_VC_MEMORY_PREFIX = "graph:chat:vc:memory";
    private static final String GRAPH_CHAT_VC_ORDER_MEMORY_PREFIX = "graph:chat:vc:order:memory";

    public void deleteAllKeys() {
        redisUtils.deleteAllKeys();
    }

    public void setToken(String token, Integer uid) {
        if (Objects.isNull(token) || Objects.isNull(uid))
            return;
        redisUtils.set(GRAPH_TOKEN_UID_PREFIX + token, uid, userConfiguration.getTokenExpires());
    }

    public Integer getUidByToken(String token) {
        Object uid = redisUtils.get(GRAPH_TOKEN_UID_PREFIX + token);
        if (Objects.isNull(uid))
            return null;
        return (Integer) uid;
    }

    public void setPermission(String authCode, Integer status) {
        if (Objects.isNull(authCode) || Objects.isNull(status))
            return;
        String reAuthCode = authCode.replace(":", "-");
        redisUtils.hSet(GRAPH_PERMISSION_PREFIX, reAuthCode, status);
    }

    public SysPermissionStatusEnum getPermissionStatus(String authCode) {
        String reAuthCode = authCode.replace(":", "-");
        Object status = redisUtils.hGet(GRAPH_PERMISSION_PREFIX, reAuthCode);
        if (Objects.isNull(status))
            return null;
        return SysPermissionStatusEnum.getByCode((Integer) status);
    }

    public void setRole(Integer roleId, Integer status) {
        if (Objects.isNull(roleId) || Objects.isNull(status))
            return;
        redisUtils.hSet(GRAPH_ROLE_PREFIX, roleId.toString(), status);
    }

    public SysRoleStatusEnum getRoleStatus(Integer roleId) {
        Object status = redisUtils.hGet(GRAPH_PERMISSION_PREFIX, roleId.toString());
        if (Objects.isNull(status))
            return null;
        return SysRoleStatusEnum.getByCode((Integer) status);
    }

    public void setRP_Relation(Integer roleId, String authCode, Integer permissionId) {
        if (Objects.isNull(roleId) || Objects.isNull(authCode) || Objects.isNull(permissionId))
            return;
        redisUtils.hSet(GRAPH_RP_RELATION_PREFIX + roleId.toString(), authCode, permissionId);
    }

    public void removeRP_Relation(Integer roleId, String authCode) {
        redisUtils.hRemove(GRAPH_RP_RELATION_PREFIX + roleId.toString(), authCode);
    }

    public Integer getRP_PermissionId(Integer roleId, String authCode) {
        Object permissionId = redisUtils.hGet(GRAPH_RP_RELATION_PREFIX + roleId.toString(), authCode);
        if (Objects.isNull(permissionId))
            return null;
        return (Integer) permissionId;
    }

    public void setRU_Relation(Integer userId, Integer roleId) {
        if (Objects.isNull(userId) || Objects.isNull(roleId))
            return;
        redisUtils.set(GRAPH_RU_ReLATION_PREFIX + userId, roleId);
    }

    public Integer getRU_RoleId(Integer userId) {
        Object roleId = redisUtils.get(GRAPH_RU_ReLATION_PREFIX + userId);
        if (Objects.isNull(roleId))
            return null;
        return (Integer) roleId;
    }

    public void incrementVisitLimit(String ip) {
        ip = ip.replace(":", "_");
        Object currentCounts = redisUtils.get(GRAPH_VISIT_LIMIT_PREFIX + ip);
        if (Objects.isNull(currentCounts)) {
            redisUtils.set(GRAPH_VISIT_LIMIT_PREFIX + ip, 1, 60L);
        } else {
            try {
                redisUtils.increment(GRAPH_VISIT_LIMIT_PREFIX + ip);
            } catch (Exception ignore) {
                redisUtils.set(GRAPH_VISIT_LIMIT_PREFIX + ip, 1, 60L);
            }
        }
    }

    public boolean isMaxVisitLimit(String ip) {
        ip = ip.replace(":", "_");
        Object currentCounts = redisUtils.get(GRAPH_VISIT_LIMIT_PREFIX + ip);
        if (Objects.isNull(currentCounts)) {
            return false;
        }
        return (Integer) currentCounts >= userConfiguration.getMaxVisitInOneMinute();
    }

    public void setImageCaptcha(String captchaKey, String captchaValue) {
        if (Objects.isNull(captchaKey) || Objects.isNull(captchaValue))
            return;
        redisUtils.set(GRAPH_CAPTCHA_IMAGE_PREFIX + captchaKey, captchaValue.toUpperCase(),
                utilsConfiguration.getCaptcha().getImageExpires());
    }

    public boolean verifyImageCaptcha(String captchaKey, String verificationCode) {
        Object captchaValue = redisUtils.get(GRAPH_CAPTCHA_IMAGE_PREFIX + captchaKey);
        if (Objects.isNull(captchaValue))
            return false;
        return Objects.equals(captchaValue.toString(), verificationCode.toUpperCase());
    }

    public void removeImageCaptcha(String captchaKey) {
        redisUtils.remove(GRAPH_CAPTCHA_IMAGE_PREFIX + captchaKey);
    }

    public void setChatVCMemory(String chatMemoryKey, String chatMemoryValue) {
        if (Objects.isNull(chatMemoryKey) || Objects.isNull(chatMemoryValue))
            return;
        redisUtils.hSet(GRAPH_CHAT_VC_MEMORY_PREFIX, chatMemoryKey, chatMemoryValue);
    }

    public void removeChatVcMemory() {
        redisUtils.remove(GRAPH_CHAT_VC_MEMORY_PREFIX);
    }

    public String getChatVCMemory(String chatMemoryKey) {
        Object memory = redisUtils.hGet(GRAPH_CHAT_VC_MEMORY_PREFIX, chatMemoryKey);
        if (Objects.isNull(memory))
            return null;
        return (String) memory;
    }

    public void setChatOrderVcMemory(String chatMemoryKey, String chatMemoryValue) {
        if (Objects.isNull(chatMemoryKey) || Objects.isNull(chatMemoryValue))
            return;
        redisUtils.hSet(GRAPH_CHAT_VC_ORDER_MEMORY_PREFIX, chatMemoryKey, chatMemoryValue);
    }

    public void removeChatOrderVcMemory() {
        redisUtils.remove(GRAPH_CHAT_VC_ORDER_MEMORY_PREFIX);
    }

    public void removeChatOrderVcMemory(String chatMemoryKey) {
        redisUtils.hRemove(GRAPH_CHAT_VC_ORDER_MEMORY_PREFIX, chatMemoryKey);
    }

    public String getChatOrderVCMemory(String chatMemoryKey) {
        Object memory = redisUtils.hGet(GRAPH_CHAT_VC_ORDER_MEMORY_PREFIX, chatMemoryKey);
        if (Objects.isNull(memory))
            return null;
        return (String) memory;
    }
}
